package org.robert.export_client.excel.builder;


import cn.hutool.core.map.MapUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.robert.export_client.aop.*;
import org.robert.export_client.excel.metadata.DependEntity;
import org.robert.export_client.excel.metadata.ExcelDictEntity;
import org.robert.export_client.excel.metadata.ExcelHeadEntity;
import org.robert.export_client.excel.metadata.IBaseExcelJson;

import java.lang.reflect.Field;
import java.util.*;

/**
 * ExcelHeadBuilder:
 *
 * @author zhaoshengtao
 * @date 2024/01/19
 */
@Getter
@AllArgsConstructor
public class ExcelHeadBuilder {

    private final  List<ExcelHeadEntity> excelHeadEntityList;

    private final  int total;

    public static ExcelHeadBuilder of(Class<?> entityClass, Map<String, Map<String, String>> dictAllMap) throws Exception {
        List<ExcelHeadEntity> propertyList = getExcelPropertyNames(entityClass, dictAllMap);
        return new ExcelHeadBuilder(Collections.unmodifiableList(propertyList), propertyList.size());
    }


    /**
     * 解析字段信息
     * @param entityClass
     * @return
     * @throws Exception
     */
    public static List<ExcelHeadEntity> getExcelPropertyNames(Class<?> entityClass, Map<String, Map<String, String>> dictAllMap) throws Exception {
        List<ExcelHeadEntity> propertyList = new ArrayList<>();
        // 用来存放拼接的字段实体
        Map<String, ExcelHeadEntity> entityHashMap = new HashMap<>();
        Field[] fields = entityClass.getDeclaredFields();
        int index = 1;
        for (Field field : fields) {

            boolean isExcelProperty = field.isAnnotationPresent(ExcelProperty.class);
            // 是否需要解析成json
            boolean isJsonExportable = field.isAnnotationPresent(ExcelJson.class);
            // 是否多个字段连接
            boolean isConnectField = field.isAnnotationPresent(ExcelFieldMerge.class);
            field.setAccessible(true);
            if (isExcelProperty) {
                ExcelHeadEntity excelHeadEntity = setExcelPropertyMap(field, index, false, dictAllMap, null);
                if(isConnectField){
                    // 放在最后面 是否多个字段连接
                    ExcelFieldMerge excelField = field.getAnnotation(ExcelFieldMerge.class);
                    String connect = excelField.connect();
                    excelHeadEntity.setConnect(true);
                    excelHeadEntity.setConnectType(connect);

                    int total = excelField.total();
                    String[] strings = new String[total];
                    strings[0] = excelHeadEntity.getFieldName();
                    excelHeadEntity.setFieldNames(strings);
                    entityHashMap.put(excelHeadEntity.getFieldName(), excelHeadEntity);
                }else{
                    propertyList.add(excelHeadEntity);
                }
                index++;

                continue;
            }
            if (isJsonExportable) {
                ExcelJson annotation = field.getAnnotation(ExcelJson.class);
                Class<? extends IBaseExcelJson> targetClass = annotation.parserFor();
                for (Field subField : targetClass.getDeclaredFields()) {
                    ExcelHeadEntity excelHeadEntity = setExcelPropertyMap(subField, index, true, dictAllMap, targetClass);
                    excelHeadEntity.setFieldName(field.getName());
                    propertyList.add(excelHeadEntity);
                    index++;
                }
                continue;
            }
            if(isConnectField){
                // 放在最后面 是否多个字段连接
                ExcelFieldMerge excelField = field.getAnnotation(ExcelFieldMerge.class);
                int sort = excelField.index();
                String value = excelField.value();
                if(StringUtils.isNotBlank(value)){
                    ExcelHeadEntity excelHeadEntity = entityHashMap.get(value);
                    if(excelHeadEntity == null){
                        continue;
                    }
                    String[] list = excelHeadEntity.getFieldNames();
                    list[sort] = field.getName();
                    excelHeadEntity.setFieldNames(list);
                    entityHashMap.put(value, excelHeadEntity);
                }
            }
        }
        propertyList.addAll(new ArrayList<>(entityHashMap.values()));
        // 根据下标排序
        propertyList.sort(Comparator.comparing(ExcelHeadEntity::getColumnIndex));
        return propertyList;
    }


    private static ExcelHeadEntity setExcelPropertyMap(Field field, int index, boolean isJson,
                                                       Map<String, Map<String, String>> dictAllMap,
                                                       Class<? extends IBaseExcelJson> targetClass){
        ExcelHeadEntity excelHeadEntity = new ExcelHeadEntity();
        String fieldName = field.getName();
        ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);

        boolean isDateTimeFormat = field.isAnnotationPresent(DateTimeFormat.class);
        boolean isDictFormat = field.isAnnotationPresent(ExportDict.class);
        boolean isColumnWidth = field.isAnnotationPresent(ColumnWidth.class);
        boolean isDepend = field.isAnnotationPresent(ExcelDepend.class);

        String columnName = excelProperty.value();
        int columnIndex = excelProperty.index();
        if(columnIndex <= 0){
            columnIndex = index;
        }
        excelHeadEntity.setJson(isJson);
        if(isJson){
            excelHeadEntity.setSubFieldName(fieldName);
            excelHeadEntity.setJson(true);
            excelHeadEntity.setJsonClazz(targetClass);
        }else{
            excelHeadEntity.setFieldName(fieldName);
        }
        excelHeadEntity.setColumnName(columnName);
        excelHeadEntity.setColumnIndex(columnIndex);
        // 判断是否需要字典转换
        if (isDictFormat && MapUtil.isNotEmpty(dictAllMap)) {
            ExportDict exportDict = field.getAnnotation(ExportDict.class);
            // 获取注解的值
            String value = exportDict.value();
            Map<String, String> map = dictAllMap.get(value);
            if(MapUtil.isNotEmpty(map)){
                boolean isSplit = exportDict.isSpilt();
                String spilt = exportDict.spilt();
                String connect = exportDict.connect();
                ExcelDictEntity dictEntity = new ExcelDictEntity(value,fieldName, map,isSplit,spilt,connect);
                excelHeadEntity.setDictEntity(dictEntity);
            }
        }

        // 判断时间解析
        if(isDateTimeFormat){
            DateTimeFormat dateTimeFormat = field.getAnnotation(DateTimeFormat.class);
            // 获取注解的值
            String value = dateTimeFormat.pattern();
            excelHeadEntity.setDateFormat(value);
        }

        // 设置字段宽度
        if(isColumnWidth){
            ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class);
            // 获取注解的值
            int value = columnWidth.value();
            excelHeadEntity.setColumnWidth(value);
        }else{
            excelHeadEntity.setColumnWidth(20);
        }

        // 判断数据依赖
        if(isDepend){
            ExcelDepend excelDepend = field.getAnnotation(ExcelDepend.class);
            DependEntity dependEntity = new DependEntity(excelDepend);
            if(dependEntity.isFixed() && dependEntity.getFixedValue() == null){
                throw new IllegalArgumentException("ExcelDepend.class 使用错误");
            }
            excelHeadEntity.setDepend(true);
            excelHeadEntity.setDependEntity(dependEntity);
        }
        return excelHeadEntity;
    }



}
